/*
 * Copyright (c) 2020, QST Innovation Technology Group Co.,Ltd and/or its affiliates. All rights reserved.
 * QST Innovation Technology Group Co.,Ltd PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */

package com.example.exporttemplate.utils;

import com.aspose.words.*;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.util.Date;
import java.util.Objects;

/**
 * AsposeWord工具类
 *
 * @author liulindong
 * @since 2022/11/3 11:28
 */
public class AsposeWordUtil {
    public static void registerWord_v_22_5() throws Exception {
        Class<?> zzjXClass = Class.forName("com.aspose.words.zzjX");
        Constructor<?> constructor = zzjXClass.getDeclaredConstructors()[0];
        constructor.setAccessible(true);
        Object zzjXInstance = constructor.newInstance();

        // zzZ7O
        Field zzZ7O = zzjXClass.getDeclaredField("zzZ7O");
        zzZ7O.setAccessible(true);
        zzZ7O.set(zzjXInstance, new Date(Long.MAX_VALUE));

        // zzBf
        Field zzZfB = zzjXClass.getDeclaredField("zzZfB");
        zzZfB.setAccessible(true);
        Class<?> zzYP3Class = Class.forName("com.aspose.words.zzYP3");
        Field zzBfField = zzYP3Class.getDeclaredField("zzBf");
        zzBfField.setAccessible(true);
        zzZfB.set(zzjXInstance, zzBfField.get(null));

        // zzZjA
        Field zzZjA = zzjXClass.getDeclaredField("zzZjA");
        zzZjA.setAccessible(true);
        zzZjA.set(null, zzjXInstance);


        Class<?> zzCnClass = Class.forName("com.aspose.words.zzCn");
        Field zzZyx = zzCnClass.getDeclaredField("zzZyx");
        zzZyx.setAccessible(true);
        zzZyx.set(null, 128);
        Field zzZ8w = zzCnClass.getDeclaredField("zzZ8w");
        zzZ8w.setAccessible(true);
        zzZ8w.set(null, false);
    }


    public static void registerWord_v_22_6() throws Exception {
        Class<?> zzcfClass = Class.forName("com.aspose.words.zzcf");
        Constructor<?> constructor = zzcfClass.getDeclaredConstructors()[0];
        constructor.setAccessible(true);
        Object zzcfInstance = constructor.newInstance();

        // zzYLF
        Field zzZ7O = zzcfClass.getDeclaredField("zzYLF");
        zzZ7O.setAccessible(true);
        zzZ7O.set(zzcfInstance, new Date(Long.MAX_VALUE));

        // zzWzN
        Field zzWzN = zzcfClass.getDeclaredField("zzWzN");
        zzWzN.setAccessible(true);
        Class<?> zzYP3Class = Class.forName("com.aspose.words.zzYh2");
        Field zzXTFField = zzYP3Class.getDeclaredField("zzXTF");
        zzXTFField.setAccessible(true);
        zzWzN.set(zzcfInstance, zzXTFField.get(null));

        // zzMc
        Field zzZjA = zzcfClass.getDeclaredField("zzMc");
        zzZjA.setAccessible(true);
        zzZjA.set(null, zzcfInstance);


        Class<?> zzCnClass = Class.forName("com.aspose.words.zzZIg");
        Field zzZyx = zzCnClass.getDeclaredField("zzXPZ");
        zzZyx.setAccessible(true);
        zzZyx.set(null, 128);
        Field zzZ8w = zzCnClass.getDeclaredField("zzZh7");
        zzZ8w.setAccessible(true);
        zzZ8w.set(null, false);
    }


    /**
     * 生成目录并更新域
     *
     * @param document 文档
     * @param builder 构建器
     * @throws Exception 更新域会抛出异常
     */
    public static void createAndUpdateTOC(Document document, DocumentBuilder builder) throws Exception {
        document.getFirstSection().getBody().prependChild(new Paragraph(document));
        // 光标移至文档开头
        builder.moveToDocumentStart();

        // “目录”两个字居中显示、加粗、宋体
        builder.getCurrentParagraph().getParagraphFormat().setAlignment(com.aspose.words.ParagraphAlignment.CENTER);
        builder.setBold(true);
        builder.getFont().setName("宋体");
        builder.writeln("目录");
        // 清清除所有样式设置
        builder.getParagraphFormat().clearFormatting();

        // 目录内容居左
        builder.getParagraphFormat().setAlignment(com.aspose.words.ParagraphAlignment.LEFT);
        // 插入目录，这是固定语法1-5支持和h1-h5
        builder.insertTableOfContents("\\o \"1-5\" \\h \\z \\u");


        // 换至下一页
        builder.insertBreak(com.aspose.words.BreakType.PAGE_BREAK);
        // 更新域
        document.updateFields();

        // 给目录设置相应的样式
        for (com.aspose.words.Field field : document.getRange().getFields()) {
            if (field.getType() == (FieldType.FIELD_PAGE_REF)) {
                FieldPageRef pageRef = (FieldPageRef) field;
                if (!Objects.equals(pageRef.getBookmarkName(), "") || pageRef.getBookmarkName().startsWith("_Toc")) {
                    Paragraph tocItem = (Paragraph) field.getStart().getAncestor(NodeType.PARAGRAPH);
                    tocItem.getParagraphFormat().setLineSpacing(15);
                    for (Run run : tocItem.getRuns()) {
                        run.getFont().setName("宋体");
                        run.getFont().setSize(12);
                        run.getFont().setBold(false);
                    }
                }
            }
        }
        // 锁定目录，避免手动更新目录后，格式失效
        for (com.aspose.words.Field field : document.getRange().getFields())
        {
            if (field.getType() == (FieldType.FIELD_TOC))
            {
                field.isLocked(true);
            }
        }
    }


    /**
     * 插入富文本时，创建一级标题(黑体四号字)
     *
     * @param title 标题内容
     * @return h1标签
     */
    private static String createH1Title(String title) {
        return "<h1><span lang=EN-US style='font-size:14.0pt;line-height:240%;font-family:黑体;\n" +
                "font-weight:normal'>" + title + "</span></h1>";
    }


    /**
     * 插入富文本时，创建二级标题(黑体小四号字)
     *
     * @param title 标题内容
     * @return h2标签
     */
    private static String createH2Title(String title) {
        return "<h2><span lang=EN-US style='font-size:12.0pt;line-height:173%;font-family:黑体;\n" +
                "font-weight:normal'>" + title + "</span></h2>";
    }


    /**
     * 插入富文本时，创建三级标题(宋体加粗小四号)
     *
     * @param title 标题内容
     * @return h3标签
     */
    private static String createH3Title(String title) {
        return "<h3><span lang=EN-US style='font-size:12.0pt;line-height:173%;font-family:宋体;'>" + title + "</span></h3>";
    }


    /**
     * 插入富文本时，手动添加正文(宋体小四号、正文行间距1.5)
     *
     * @param content 标题
     * @return 带样式正文内容
     */
    public static String createContent(String content) {
        return "<p class=MsoNormal style='line-height:150%'><span style='font-size:12.0pt;\n" +
                "line-height:150%;font-family:宋体'>" + content + "<span lang=EN-US></span></span></p>";
    }


    /**
     * 插入富文本时，手动创建标题
     *
     * @param title 富文本标题内容
     * @param level 标题等级
     * @return <h></h>标签
     */
    public static String createHeading(String title, int level) {
        switch (level) {
            case 1:
                return createH1Title(title);
            case 2:
                return createH2Title(title);
            case 3:
                return createH3Title(title);
            default:
                return createH1Title(title);
        }
    }



    /**
     * 返回html2docx时，需要的样式标签
     *
     * @return <style></style>
     */
    public static String createStyleLabel() {
        return "<style> " +
                "image{width:200;height:200} " +
                "table{border:1px solid black;border-collapse: collapse;} " +
                "tr{border:1px solid black;} " +
                "td{border:1px solid black;} " +
                "</style>";
    }


    /**
     * 返回完整的网页标签
     *
     * @param styleLabel 样式标签
     * @param body 网页body
     * @return html
     */
    public static String getHtml(String styleLabel, String body) {
        StringBuffer sb = new StringBuffer();
        sb.append("<html>");
        sb.append("<head>").append(styleLabel).append("</head>");
        sb.append("<body>");
        // 内容体
        sb.append(body);
        sb.append("</body></html>");
        return sb.toString();
    }


    public static void addHeaderAndFooter(Document document) throws Exception {
        HeaderFooter footer = new HeaderFooter(document, HeaderFooterType.FOOTER_PRIMARY);
        document.getFirstSection().getHeadersFooters().add(footer);

        //页脚段落
        Paragraph footerPara = new Paragraph(document);
        footerPara.getParagraphFormat().setAlignment(ParagraphAlignment.CENTER);
        Run footerparaRun = new Run(document);
        footerparaRun.getFont().setName("宋体");
        footerparaRun.getFont().setSize(10.0);//小5号字体
        footerPara.appendField(FieldType.FIELD_PAGE, true);//当前页码
        footerPara.appendChild(footerparaRun);
        footer.appendChild(footerPara);
    }
}
